#include <future>
int calculate() {
    // 模拟一个耗时的计算
    std::this_thread::sleep_for(std::chrono::seconds(1));
    return 42;
}

int main() {
    std::future<int> future_result = std::async(std::launch::async, calculate);
    // 在这里可以做其他的事情
    int result = future_result.get(); // 获取异步操作的结果
    std::cout << result << std::endl; // 输出42
    return 0;
}

/*packaged_task
std::packaged_task是一个类模板，用于将一个可调用对象（如函数、函数对象或 Lambda 表达式）封装成一个异步操作，
并返回一个std::future对象，表示异步操作的结果。
packaged_task可以方便地将一个函数或可调用对象转换成一个异步操作，供其他线程使用。*/
//1.定义可调用对象：
int calculate(int x, int y) {
    return x + y;
}
//2.创建 packaged_task 对象：
std::packaged_task<int(int, int)> task(calculate);
std::future<int> future_result = task.get_future();
//3.在其他线程中执行异步操作：
std::thread t(std::move(task), 1, 2);
t.join();
//4.获取异步操作的结果：
int result = future_result.get();
std::cout << result << std::endl; // 输出3
/*
在此例中，我们成功地将一个函数calculate封装成了一个异步操作，并在其他线程中执行。
通过packaged_task和future对象，我们可以方便地实现异步编程，使得代码更加简洁和易于维护。
*/

/*
 promise
std::promise 是一个类模板，用于在一个线程中产生一个值，并在另一个线程中获取这个值。
promise 通常与 future 和 async 一起使用，用于实现异步编程。
*/
//1.创建 promise 对象：
std::promise<int> p;
//2.获取 future 对象：
std::future<int> f = p.get_future();
//3.在其他线程中设置值：
std::thread t([&p]() {
    p.set_value(42);
    });
t.join();
//4.在主线程中获取值：
int result = f.get();
std::cout << result << std::endl; // 输出42
/*
在此例中，我们成功地使用promise和future对象实现了跨线程的值传递。
通过promise和future对象，我们可以方便地实现异步编程，避免了手动创建线程和管理线程的麻烦。
*/





/*
std::atomic是 C++11 标准库中的一个模板类，用于实现多线程环境下的原子操作。它提供了一种线程安全的方式来访问和修改共享变量，可以避免多线程环境中的数据竞争问题。
std::atomic的使用方式类似于普通的 C++ 变量，但是它的操作是原子性的。也就是说，在多线程环境下，多个线程同时对同一个std::atomic变量进行操作时，不会出现数据竞争问题。

常用的 std::atomic 操作
load()：将 std::atomic 变量的值加载到当前线程的本地缓存中，并返回这个值。

store(val)：将val的值存储到std::atomic变量中，并保证这个操作是原子性的。

exchange(val)：将val的值存储到std::atomic变量中，并返回原先的值。

compare_exchange_weak(expected, val)和compare_exchange_strong(expected, val)：

比较std::atomic变量的值和expected的值是否相同，如果相同，则将val的值存储到std::atomic变量中，并返回true；
否则，将std::atomic变量的值存储到expected中，并返回false。
*/
// 示例代码
// 以下是一个示例，演示了如何使用std::atomic进行原子操作:

#include <atomic>
#include <iostream>
#include <thread>

std::atomic<int> count = 0;

void increment() {
    for (int i = 0; i < 1000000; ++i) {
        count++;
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);
    t1.join();
    t2.join();
    std::cout << count << std::endl;
    return 0;
}
// 在这个示例中，我们定义了一个 std::atomic<int>类型的变量count，并将其初始化为 0。
//然后，我们启动两个线程分别执行increment函数，这个函数的作用是将count变量的值加一，执行一百万次。最后，我们在主线程中输出count 变量的值。

// 由于count变量是一个std::atomic类型的变量，因此对它进行操作是原子性的，不会出现数据竞争问题。在这个示例中，最终输出的count变量的值应该是 2000000。